package connpool

import (
	"net"
	"sync"
)

var cltid uint32 = 1

type RoutHandler func(*CltNode, *[]byte)

type CltPool struct {
	CltList     sync.Map
	BlockWorker chan *Msg
	MsgQueue    chan *Msg
	routHand    map[uint32]RoutHandler
	quit        chan uint32
}

func NewCltPool(b chan *Msg, m chan *Msg) (cltp *CltPool) {
	cltp = &CltPool{
		CltList:     sync.Map{},
		BlockWorker: b,
		MsgQueue:    m,
		quit:        make(chan uint32, 100),
	}
	go cltp.DeleteNode()
	//异步消息处理
	go cltp.RegistHandler(200, func(node *CltNode, data *[]byte) {
		msg := NewMsg(node, data)
		cltp.MsgQueue <- msg
	})
	//同步消息处理
	go cltp.RegistHandler(100, func(node *CltNode, data *[]byte) {
		msg := NewMsg(node, data)
		cltp.BlockWorker <- msg
	})
	return
}

func (c *CltPool) DeleteNode() {
	for {
		cid := <-c.quit
		if v, ok := c.CltList.Load(cid); ok {
			v.(*CltNode).Close()
			c.CltList.Delete(cid)
		}
	}
}

func (c *CltPool) AddNode(conn net.Conn) {
	node := NewCltNode(cltid, conn, c.quit)
	c.CltList.Store(node.ID, node)
	go node.Read(c.routHand)
	cltid++
}

func (c *CltPool) RegistHandler(purpose uint32, hand RoutHandler) {
	c.routHand[purpose] = hand
}
